package ch.qos.logback.classic.log4j2;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.slf4j.event.KeyValuePair;

import com.fasterxml.jackson.databind.JsonNode;
import com.networknt.config.Config;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggerContextVO;
import ch.qos.logback.classic.spi.ThrowableProxyVO;

public class LoggingEvent implements ILoggingEvent {
	static LoggerContextVO lcvo = new LoggerContextVO("log4j2", null, System.currentTimeMillis());
	private JsonNode json;

	public LoggingEvent(JsonNode json) {
		this.json = json;
	}

	@Override
	public String getThreadName() {
		return json.get("thread").asText();
	}

	@Override
	public Level getLevel() {
		return Level.toLevel(json.get("level").asText());
	}

	@Override
	public String getMessage() {
		return json.get("message").asText();
	}

	@Override
	public Object[] getArgumentArray() {
		return null;
	}

	@Override
	public String getFormattedMessage() {
		return null;
	}

	@Override
	public String getLoggerName() {
		return json.get("loggerName").asText();
	}

	@Override
	public LoggerContextVO getLoggerContextVO() {
		return lcvo;
	}

	@Override
	public IThrowableProxy getThrowableProxy() {
		if (json.has("thrown")) {
			return ThrowableProxyVO.build(new ThrowableProxy(json.get("thrown")));
		}
		return null;
	}

	@Override
	public StackTraceElement[] getCallerData() {
		return null;
	}

	@Override
	public boolean hasCallerData() {
		return false;
	}

	@Override
	public List<Marker> getMarkerList() {
		if (json.has("marker")) {
			return Arrays.asList(MarkerFactory.getDetachedMarker(json.get("marker").get("name").asText()));
		}
		return null;
	}

	@Override
	public Map<String, String> getMDCPropertyMap() {
		return getMdc();
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<String, String> getMdc() {
		if (json.has("contextMap")) {
			return Config.getInstance().getMapper().convertValue(json.get("contextMap"), Map.class);
		}
		return Collections.emptyMap();
	}

	@Override
	public long getTimeStamp() {
		return 1000 * Long.parseLong(json.get("instant").get("epochSecond").asText());
	}

	@Override
	public int getNanoseconds() {
		return -1;
	}

	@Override
	public long getSequenceNumber() {
		return 0;
	}

	@Override
	public List<KeyValuePair> getKeyValuePairs() {
		return null;
	}

	@Override
	public void prepareForDeferredProcessing() {
	}
}